﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DiscoveryLogic.UI.Filters
{
    public class MouseManager
    {
        #region Public Variables

        double mouseDownValueX = -1;
        double mouseDownValueY = -1;
        double mouseDownPositionX;
        double mouseDownPositionY;

        string sliderOrientation = "horizontal";
        double sliderBarInitial;
        double sliderBarDistance;
        double sliderThumbWidth;

        #endregion

        #region Constructors

        public MouseManager() :
            this("horizontal", 0, 0, 0)
        {
        }

        public MouseManager(string sliderOrientation, double sliderBarLeft, double sliderBarWidth, double sliderThumbWidth)
        {
            this.sliderOrientation = sliderOrientation;
            this.sliderBarInitial = sliderBarLeft;
            this.sliderBarDistance = sliderBarWidth;
            this.sliderThumbWidth = sliderThumbWidth;
        }

        #endregion

        #region Public Methods

        // Lifting
        public void OnMouseEnterLift(object sender, EventArgs eventArgs)
        {
            TranslateTransform transform = new TranslateTransform();
            transform.X = 0;
            transform.Y = -4;

            ((FrameworkElement)sender).RenderTransform = transform;
        }

        public void OnMouseLeaveLower(object sender, EventArgs eventArgs)
        {
            TranslateTransform transform = new TranslateTransform();
            transform.X = 0;
            transform.Y = 0;

            ((FrameworkElement)sender).RenderTransform = transform;
        }

        // Changing mouse cursors
        public void OnMouseEnterHand(object sender, EventArgs eventArgs)
        {
            ((FrameworkElement)sender).Cursor = Cursors.Hand;
        }

        public void OnMouseLeaveArrow(object sender, EventArgs eventArgs)
        {
            ((FrameworkElement)sender).Cursor = Cursors.Arrow;
        }

        // Navigating between screens
        public void OnMouseClickNext(object sender, EventArgs eventArgs)
        {
            if (changeStep != null)
            {
                CustomEventArgs args = new CustomEventArgs();
                args.NextStep = true;
                changeStep(this, args);
            }
        }

        public void OnMouseClickBack(object sender, EventArgs eventArgs)
        {
            if (changeStep != null)
            {
                CustomEventArgs args = new CustomEventArgs();
                args.NextStep = false;
                changeStep(this, args);
            }
        }

        // Slider events
        public void SliderMouseDown(object sender, MouseEventArgs eventArgs)
        {
            ((UIElement)sender).CaptureMouse();

            mouseDownValueX = (double)((UIElement)sender).GetValue(Canvas.LeftProperty);
            mouseDownValueY = (double)((UIElement)sender).GetValue(Canvas.TopProperty);
            mouseDownPositionX = eventArgs.GetPosition(null).X;
            mouseDownPositionY = eventArgs.GetPosition(null).Y;
        }

        public void SliderMouseUp(object sender, EventArgs eventArgs)
        {
            ((UIElement)sender).ReleaseMouseCapture();
            mouseDownValueX = -1;
            mouseDownValueY = -1;
        }

        public void SliderMouseMove(object sender, MouseEventArgs eventArgs)
        {
            // If mouse button is still in down position
            if (mouseDownValueX != -1 && mouseDownValueY != -1)
            {

                // Find slider bar and its dimensions                
                double sliderBarMax = sliderBarInitial
                                    + sliderBarDistance
                                    - sliderThumbWidth / 2;
                double sliderBarMin = sliderBarInitial - sliderThumbWidth / 2;


                // Ensure that slider thumb doesn`t go beyond min or max
                double newValue;

                if (sliderOrientation == "vertical")
                {
                    newValue = mouseDownValueY + (eventArgs.GetPosition(null).Y - mouseDownPositionY);
                }
                else
                {
                    newValue = mouseDownValueX + (eventArgs.GetPosition(null).X - mouseDownPositionX);
                }

                if (newValue > sliderBarMax)
                {
                    newValue = sliderBarMax;
                }

                if (newValue < sliderBarMin)
                {
                    newValue = sliderBarMin;
                }

                // Set event arg with new value 
                if (sliderMove != null)
                {
                    CustomEventArgs args = new CustomEventArgs();
                    args.SliderThumbValue = newValue;
                    sliderMove(this, args);
                }
            }

        }

        // Drag events
        public void DragMouseMove(object sender, MouseEventArgs eventArgs)
        {
            // If mouse button is still in down position
            if (mouseDownValueX != -1 && mouseDownValueY != -1)
            {
                double newValueX;
                double newValueY;

                double currentX = eventArgs.GetPosition(null).X;
                double currentY = eventArgs.GetPosition(null).Y;

                newValueY = mouseDownValueY + (currentY - mouseDownPositionY);
                newValueX = mouseDownValueX + (currentX - mouseDownPositionX);

                /*
                PieSlice slice = (PieSlice)sender;

                TransformGroup tg = new TransformGroup();
                TranslateTransform translate = new TranslateTransform();
                translate.X = newValueX;
                translate.Y = newValueY;
                tg.Children.Add(translate);

                slice.SetSliceTransform(tg);
                */

                // Set event arg with new value 



                if (dragMove != null)
                {
                    CustomEventArgs args = new CustomEventArgs();
                    args.DragX = newValueX;
                    args.DragY = newValueY;
                    args.currentMouseX = currentX;
                    args.currentMouseY = currentY;
                    dragMove(this, args, eventArgs);
                }

            }
        }

        public void DragMouseDown(object sender, MouseEventArgs eventArgs)
        {
            SliderMouseDown(sender, eventArgs);
            if (dragMouseDown != null)
            {
                dragMouseDown(this, eventArgs);
            }
        }

        public void DragMouseUp(object sender, MouseEventArgs eventArgs)
        {
            SliderMouseUp(sender, eventArgs);

            if (dragMouseUp != null)
            {
                dragMouseUp(this, eventArgs);
            }
        }



        #endregion

        #region Events

        public event NextStepEventHandler changeStep;
        public event SliderMoveEventHandler sliderMove;
        public event DragMoveEventHandler dragMove;
        public event DragMouseDownEventHandler dragMouseDown;
        public event DragMouseUpEventHandler dragMouseUp;
        public event MouseEventHandler mouseUp;
        public event EventHandler mouseDown;

        #endregion

        #region Public Delegates

        public delegate void NextStepEventHandler(object sender, CustomEventArgs eventArgs);
        public delegate void SliderMoveEventHandler(object sender, CustomEventArgs eventArgs);
        public delegate void DragMoveEventHandler(object sender, CustomEventArgs eventArgs, MouseEventArgs mouseArgs);
        public delegate void DragMouseDownEventHandler(object sender, MouseEventArgs eventArgs);
        public delegate void DragMouseUpEventHandler(object sender, MouseEventArgs eventArgs);

        #endregion
    }
}
